package dice.sinanya.tools.makedata;

import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import com.itextpdf.text.pdf.draw.DottedLineSeparator;
import dice.sinanya.system.MessagesSystem;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.Map;

public class SavePdf {
    public String info = "版本号:" + MessagesSystem.VERSIONS + "\n" +
            "大家好，我是开发者斯塔尼亚\n" +
            "塔系核心（虽然一开始只是单纯的叫斯塔尼亚制作的骰点核心，最后传成这个名字了，就这么叫吧）\n" +
            "是一种强调骰娘之间联系、数据共享，并旨在提供跑团常用功能之余，尽可能为KP、PL提供额外方便的核心。\n" +
            "\n" +
            "它的特点诸如:\n" +
            "1. 所有我方骰子共享人物卡、共享骰点历史、共享日志记录进度等。\n" +
            "    这意味着，你只需要录入一次人物卡，就可以在多个人物卡之间切换，而无需再次录入，即使换了一个群使用其它骰子也无需重新录入\n" +
            "    我们都知道，COC是一个TRPG游戏，而RPG游戏往往你可以持有多个角色。这很正常，就好比你玩一个可以新建角色的单机游戏，比如魔兽世界或暗黑三或者DNF，只允许建立一个角色才是奇怪的事情，对吧？换了一台电脑（骰子）登陆后发现角色没了，更不正常，对吧？\n" +
            "    同时，即使骰子失去响应（比如被冻结或者服务崩溃），也不会因此而丢失log日志，我方其它骰子均可以接着记录\n" +
            "    这一切工作的最终目的是:使骰子之间实现跑团功能上的绝对等价，玩家关心的是骰子的功能，而非把骰子当做宠物去养，所以骰子之间应该是等价、可替换的\n" +
            "\n" +
            "2. 使用team和stc功能协助kp与pl管理跑团中的血量、san值变化，尽一切可能的降低KP、PL在跑团中的操作繁琐度。\n" +
            "    kp使用.team直观的查看所有人的血量、san、DB等，并使用.team hp @A @B 1d2对所有成员血量进行扣除\n" +
            "    也可以由PL使用.stc hp-1d2进行快速扣除\n" +
            "    这个工作原本是需要由kp操作多张人物卡进行的，但它既不方便公示给PL们确认，也操作过于繁琐会打断部分KP的带团节奏。\n" +
            "    我认为，任何记录性、计算性的工作都不是跑团的乐趣，跑团的乐趣是扮演、是屏幕前的你与故事的互动，而非去操作各种各样的东西去记录。所以这部分应该让一个机器来完成\n" +
            "\n" +
            "3. 强调更符合跑团直觉的功能设计\n" +
            "    你可以使用.group simple 1来关闭骰子的个性化语句降低干扰\n" +
            "    也可以用.group rank 1的抢占功能来避免跑团过程中被打断\n" +
            "        它允许多个骰子自行选举出最快的一个提供服务，譬如你同时拉3个我这边的骰子，并开启抢占。假设共有A、B、C三个\n" +
            "        这时A先提供服务，B和C即使处于开启状态也不会响应任何指令。一旦A挂起（无论任何原因），B和C中的一个都会立刻接替A提供服务\n" +
            "        假设A后续重新可以用了，它也会进入静默队列，直到之前提供服务的骰子失去作用后才和剩余人竞争服务位\n" +
            "\n" +
            "此外，还有很多其它特点，在下面的命令大全里可以看到。如果你有更好的想法，也随时可以到群里和我们沟通，或者进入论坛:https://sinanya.com/discuz/forum.php 发帖反馈，或者使用.send命令和我们沟通\n" +
            "\n" +
            "那么，非常抱歉在开始时夹杂了这么多私活耽误了你的时间，后面的内容是完整的命令列表，有任何不懂得内容也可以到群或论坛中询问";

    public void save(String name, LinkedHashMap<String, String> text) throws DocumentException, IOException {
        Document doc = new Document(PageSize.A4, 48, 48, 60, 65);
        PdfWriter contentWriter = PdfWriter.getInstance(doc, new ByteArrayOutputStream());
        //设置事件
        SavePdf.ContentEvent event = new SavePdf.ContentEvent();
        contentWriter.setPageEvent(event);

        //存目录监听 开始
        doc.open();
        ArrayList<Chapter> chapterList = new ArrayList<Chapter>();
        Chapter chapter = new Chapter(new Paragraph("前言  ", setFont(18f)), 1);

        Paragraph paragraph = new Paragraph("\n\n\n" + info, setFont(8f));
        PdfPTable table = createTable(1);
        table.addCell(createCell(paragraph));
        table.setSplitLate(false);
        table.setSplitRows(true);
        chapter.add(table);

        doc.add(chapter);
        chapterList.add(chapter); //保存章节内容

        chapter = new Chapter(new Paragraph("命令说明  ", setFont(18f)), 2);
        for (Map.Entry<String, String> map : text.entrySet()) {
            Section subSection = chapter.addSection(new Paragraph("   \t" + map.getKey(), setFont(12f)));
            subSection.setIndentationLeft(10);
            paragraph = new Paragraph(map.getValue(), setFont(8f));
            table = createTable(1);
            table.addCell(createCell(paragraph));
            table.setSplitLate(false);
            table.setSplitRows(true);
            subSection.add(table);
        }

        doc.add(chapter);
        chapterList.add(chapter); //保存章节内容

        chapter = new Chapter(new Paragraph("更新日志  ", setFont(18f)), 2);
        for (String update : MessagesSystem.UPDATE) {
            paragraph = new Paragraph(update, setFont(8f));
            table = createTable(1);
            table.addCell(createCell(paragraph));
            table.setSplitLate(false);
            table.setSplitRows(true);
            chapter.add(table);
        }

        doc.add(chapter);
        chapterList.add(chapter); //保存章节内容


        doc.close();
        //存目录监听 结束

        Document document = new Document(PageSize.A4, 48, 48, 60, 65);
        String path = name;
        String dir = "./";
        File file = new File(URLDecoder.decode(dir + path, "UTF-8"));
        if (!file.exists()) {
            file.createNewFile();
        } else {
            file.delete();
            file.createNewFile();
        }
        path = dir + File.separator + path;
        FileOutputStream os = new FileOutputStream(path);
        PdfWriter writer = PdfWriter.getInstance(document, os);
        SavePdf.IndexEvent indexEvent = new SavePdf.IndexEvent();
        writer.setPageEvent(indexEvent);
        document.open();

        //添加章节目录
        Chapter indexChapter = new Chapter(new Paragraph("目录：", setFont(20f)), 0);
        indexChapter.setNumberDepth(-1);                              // 设置数字深度
        for (Map.Entry<String, Integer> index : event.index.entrySet()) {
            String key = index.getKey();
            String keyValue = key;
            float size = 18f;
            if (countInString(key, ".") == 2) { //小标题缩进判断, 如有三级标题自己添加判断
                keyValue = "          " + key;
                size = 15f;
            } else if (countInString(key, ".") == 3) {
                keyValue = "          " + "          " + key;
                size = 12f;
            }
            paragraph = new Paragraph(keyValue, setFont(size));

            Chunk chunk0101 = new Chunk(new DottedLineSeparator());

            Chunk pageno = new Chunk(index.getValue() + "    ");

            Chunk chunk0102 = new Chunk(pageno);

            //加入点点
            paragraph.add(chunk0101);
            //加入页码
            paragraph.add(chunk0102);

            indexChapter.add(paragraph);
        }

        document.add(indexChapter);

        document.newPage();

        //添加内容
        for (Chapter c : chapterList) {
            indexEvent.body = true;
            document.add(c);
        }

        document.close();
        os.close();
    }


    //根据目录编号的长度判断菜单的等级   例：1.1.1.  长度为3
    public int countInString(String str1, String str2) {
        int total = 0;
        for (String tmp = str1; tmp != null && tmp.length() >= str2.length(); ) {
            if (tmp.indexOf(str2) == 0) {
                total++;
                tmp = tmp.substring(str2.length());
            } else {
                tmp = tmp.substring(1);
            }
        }
        return total;
    }

    //设置字体
    public Font setFont(Float fontsize) {
        Font font = new Font();
        try {
            BaseFont bfComic = BaseFont.createFont("src/main/resources/msyh.ttf",
                    BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
            font = new Font(bfComic, fontsize, Font.NORMAL, new BaseColor(0, 0, 0));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return font;
    }

    //创建表格
    public PdfPTable createTable(int colume) {
        PdfPTable table = new PdfPTable(colume);
        table.setHorizontalAlignment(Element.ALIGN_CENTER);
        table.setTotalWidth(400);
        table.setLockedWidth(true);
        table.getDefaultCell().setBorder(0);
        return table;
    }

    //创建单元格
    public PdfPCell createCell(Element element) {
        PdfPCell cell = new PdfPCell();
        cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
        cell.setBorderWidth(0);
        cell.addElement(element);
        return cell;
    }

    //页码监听
    private static class ContentEvent extends PdfPageEventHelper {

        Map<String, Integer> index = new LinkedHashMap<String, Integer>();
        private int page;

        @Override
        public void onStartPage(PdfWriter writer, Document document) {
            page++;
        }

        @Override
        public void onChapter(PdfWriter writer, Document document, float paragraphPosition, Paragraph title) {
            index.put(title.getContent(), page);
        }

        @Override
        public void onSection(PdfWriter writer, Document document, float paragraphPosition, int depth, Paragraph title) {
            onChapter(writer, document, paragraphPosition, title);
        }
    }

    //根据页码加页脚
    private class IndexEvent extends PdfPageEventHelper {

        private int page;
        private boolean body;

        @Override
        public void onEndPage(PdfWriter writer, Document document) {
            if (body) {
                page++;
                //设置页脚页码
                //页码是奇数在右边，偶数在左边
                float x = page % 2 == 0 ? document.left() - 20 : document.right() + 20;
                ColumnText.showTextAligned(writer.getDirectContent(), Element.ALIGN_CENTER, new Phrase(page + ""),
                        x, document.bottom() - 40, 0);
            }
        }
    }
}
